package com.zhouxiaoxuan13.consumer.controller;

import com.zhouxiaoxuan13.consumer.feign.LoadBalancerServiceClient;
import com.zhouxiaoxuan13.consumer.feign.PromotionServiceClient;
import com.zhouxiaoxuan13.consumer.monitor.CircuitBreakerMonitor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 熔断器测试控制器
 * 用于演示和测试Spring Cloud CircuitBreaker功能
 */
@Slf4j
@RestController
@RequestMapping("/circuit-breaker")
@CrossOrigin(originPatterns = "*")
public class CircuitBreakerController {

    @Autowired
    private LoadBalancerServiceClient loadBalancerServiceClient;

    @Autowired
    private PromotionServiceClient promotionServiceClient;

    @Autowired
    private CircuitBreakerMonitor circuitBreakerMonitor;

    private final AtomicLong testCounter = new AtomicLong(0);

    // ==================== 熔断器基础测试 ====================

    /**
     * 测试慢响应熔断
     */
    @GetMapping("/test-slow-response")
    public ResponseEntity<Map<String, Object>> testSlowResponse(
            @RequestParam(value = "delay", defaultValue = "5000") int delay,
            @RequestParam(value = "times", defaultValue = "1") int times) {
        
        long testNum = testCounter.incrementAndGet();
        log.info("=== 熔断器慢响应测试 #{} ===", testNum);
        
        Map<String, Object> result = new HashMap<>();
        result.put("testNumber", testNum);
        result.put("testType", "慢响应熔断测试");
        result.put("delay", delay + "ms");
        result.put("times", times);
        result.put("timestamp", LocalDateTime.now().toString());
        
        try {
            for (int i = 1; i <= times; i++) {
                log.info("第 {}/{} 次调用慢响应接口", i, times);
                ResponseEntity<Map<String, Object>> response = loadBalancerServiceClient.slowResponse(delay);
                result.put("call_" + i, response.getBody());
            }
            result.put("status", "success");
            result.put("message", "慢响应测试完成");
        } catch (Exception e) {
            log.error("慢响应测试失败: {}", e.getMessage());
            result.put("status", "error");
            result.put("message", "慢响应测试失败: " + e.getMessage());
            result.put("error", e.getClass().getSimpleName());
        }

        // 测试完成后输出熔断器状态
        log.info("📊 慢响应测试完成，输出熔断器状态:");
        circuitBreakerMonitor.printAllCircuitBreakerStatus();

        return ResponseEntity.ok(result);
    }

    /**
     * 测试异常熔断
     */
    @GetMapping("/test-error-response")
    public ResponseEntity<Map<String, Object>> testErrorResponse(
            @RequestParam(value = "errorRate", defaultValue = "80") int errorRate,
            @RequestParam(value = "times", defaultValue = "10") int times) {
        
        long testNum = testCounter.incrementAndGet();
        log.info("=== 熔断器异常测试 #{} ===", testNum);
        
        Map<String, Object> result = new HashMap<>();
        result.put("testNumber", testNum);
        result.put("testType", "异常熔断测试");
        result.put("errorRate", errorRate + "%");
        result.put("times", times);
        result.put("timestamp", LocalDateTime.now().toString());
        
        int successCount = 0;
        int errorCount = 0;
        int fallbackCount = 0;
        
        for (int i = 1; i <= times; i++) {
            try {
                log.info("第 {}/{} 次调用异常接口", i, times);
                ResponseEntity<Map<String, Object>> response = loadBalancerServiceClient.errorResponse(errorRate);
                
                Map<String, Object> responseBody = response.getBody();
                if (responseBody != null && "fallback".equals(responseBody.get("status"))) {
                    fallbackCount++;
                    result.put("call_" + i, "fallback response");
                } else {
                    successCount++;
                    result.put("call_" + i, "success");
                }
            } catch (Exception e) {
                errorCount++;
                result.put("call_" + i, "error: " + e.getMessage());
                log.warn("第 {} 次调用失败: {}", i, e.getMessage());
            }
        }
        
        result.put("successCount", successCount);
        result.put("errorCount", errorCount);
        result.put("fallbackCount", fallbackCount);
        result.put("status", "completed");
        result.put("message", String.format("异常测试完成 - 成功: %d, 错误: %d, 降级: %d",
                successCount, errorCount, fallbackCount));

        // 测试完成后输出熔断器状态
        log.info("📊 异常测试完成，输出熔断器状态:");
        circuitBreakerMonitor.printAllCircuitBreakerStatus();

        return ResponseEntity.ok(result);
    }

    /**
     * 测试服务不可用熔断
     */
    @GetMapping("/test-unavailable-response")
    public ResponseEntity<Map<String, Object>> testUnavailableResponse(
            @RequestParam(value = "times", defaultValue = "5") int times) {
        
        long testNum = testCounter.incrementAndGet();
        log.info("=== 熔断器服务不可用测试 #{} ===", testNum);
        
        Map<String, Object> result = new HashMap<>();
        result.put("testNumber", testNum);
        result.put("testType", "服务不可用熔断测试");
        result.put("times", times);
        result.put("timestamp", LocalDateTime.now().toString());
        
        int successCount = 0;
        int errorCount = 0;
        int fallbackCount = 0;
        
        for (int i = 1; i <= times; i++) {
            try {
                log.info("第 {}/{} 次调用不可用接口", i, times);
                ResponseEntity<Map<String, Object>> response = loadBalancerServiceClient.unavailableResponse();
                
                Map<String, Object> responseBody = response.getBody();
                if (responseBody != null && "fallback".equals(responseBody.get("status"))) {
                    fallbackCount++;
                    result.put("call_" + i, "fallback response");
                } else {
                    successCount++;
                    result.put("call_" + i, "success (unexpected)");
                }
            } catch (Exception e) {
                errorCount++;
                result.put("call_" + i, "error: " + e.getMessage());
                log.warn("第 {} 次调用失败: {}", i, e.getMessage());
            }
        }
        
        result.put("successCount", successCount);
        result.put("errorCount", errorCount);
        result.put("fallbackCount", fallbackCount);
        result.put("status", "completed");
        result.put("message", String.format("服务不可用测试完成 - 成功: %d, 错误: %d, 降级: %d",
                successCount, errorCount, fallbackCount));

        // 测试完成后输出熔断器状态
        log.info("📊 服务不可用测试完成，输出熔断器状态:");
        circuitBreakerMonitor.printAllCircuitBreakerStatus();

        return ResponseEntity.ok(result);
    }

    // ==================== 综合熔断器测试 ====================

    /**
     * 综合熔断器测试
     * 模拟真实场景下的各种故障情况
     */
    @GetMapping("/comprehensive-test")
    public ResponseEntity<Map<String, Object>> comprehensiveTest() {
        long testNum = testCounter.incrementAndGet();
        log.info("=== 综合熔断器测试 #{} ===", testNum);
        
        Map<String, Object> result = new HashMap<>();
        result.put("testNumber", testNum);
        result.put("testType", "综合熔断器测试");
        result.put("timestamp", LocalDateTime.now().toString());
        
        // 测试1: 正常调用
        log.info("步骤1: 测试正常调用");
        try {
            ResponseEntity<Map<String, Object>> normalResponse = loadBalancerServiceClient.getInfo();
            result.put("step1_normal", "success");
            result.put("step1_data", normalResponse.getBody());
        } catch (Exception e) {
            result.put("step1_normal", "error: " + e.getMessage());
        }
        
        // 测试2: 慢响应
        log.info("步骤2: 测试慢响应");
        try {
            ResponseEntity<Map<String, Object>> slowResponse = loadBalancerServiceClient.slowResponse(3000);
            result.put("step2_slow", "success");
            result.put("step2_data", slowResponse.getBody());
        } catch (Exception e) {
            result.put("step2_slow", "error: " + e.getMessage());
        }
        
        // 测试3: 高错误率
        log.info("步骤3: 测试高错误率");
        try {
            ResponseEntity<Map<String, Object>> errorResponse = loadBalancerServiceClient.errorResponse(90);
            result.put("step3_error", "success");
            result.put("step3_data", errorResponse.getBody());
        } catch (Exception e) {
            result.put("step3_error", "error: " + e.getMessage());
        }
        
        // 测试4: 服务不可用
        log.info("步骤4: 测试服务不可用");
        try {
            ResponseEntity<Map<String, Object>> unavailableResponse = loadBalancerServiceClient.unavailableResponse();
            result.put("step4_unavailable", "success");
            result.put("step4_data", unavailableResponse.getBody());
        } catch (Exception e) {
            result.put("step4_unavailable", "error: " + e.getMessage());
        }
        
        result.put("status", "completed");
        result.put("message", "综合熔断器测试完成");

        // 测试完成后输出熔断器状态
        log.info("📊 综合测试完成，输出熔断器状态:");
        circuitBreakerMonitor.printAllCircuitBreakerStatus();

        return ResponseEntity.ok(result);
    }

    /**
     * 获取熔断器测试统计信息
     */
    @GetMapping("/stats")
    public ResponseEntity<Map<String, Object>> getStats() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalTests", testCounter.get());
        stats.put("timestamp", LocalDateTime.now().toString());
        stats.put("availableTests", Map.of(
            "slow-response", "/circuit-breaker/test-slow-response",
            "error-response", "/circuit-breaker/test-error-response",
            "unavailable-response", "/circuit-breaker/test-unavailable-response",
            "comprehensive", "/circuit-breaker/comprehensive-test",
            "status", "/circuit-breaker/status"
        ));
        stats.put("message", "熔断器测试统计信息");

        return ResponseEntity.ok(stats);
    }

    /**
     * 获取熔断器状态信息并在控制台输出
     */
    @GetMapping("/status")
    public ResponseEntity<Map<String, Object>> getCircuitBreakerStatus() {
        log.info("🔍 ==================== 熔断器状态查询 ====================");

        // 在控制台输出所有熔断器状态
        circuitBreakerMonitor.printAllCircuitBreakerStatus();

        Map<String, Object> response = new HashMap<>();
        response.put("message", "熔断器状态信息已在控制台输出");
        response.put("timestamp", LocalDateTime.now().toString());
        response.put("note", "请查看控制台日志获取详细的熔断器状态信息");

        log.info("🔍 ========================================================");

        return ResponseEntity.ok(response);
    }

    /**
     * 重置测试计数器
     */
    @PostMapping("/reset")
    public ResponseEntity<Map<String, Object>> resetCounter() {
        long previousCount = testCounter.getAndSet(0);
        
        Map<String, Object> response = new HashMap<>();
        response.put("message", "熔断器测试计数器已重置");
        response.put("previousCount", previousCount);
        response.put("currentCount", testCounter.get());
        response.put("timestamp", LocalDateTime.now().toString());
        
        return ResponseEntity.ok(response);
    }
}
